#include "JsApp.h"
#include "screen_device_proxy.h"
#include "VirtualScreen.h"
#include "input_device_manager.h"
#include "graphic_startup.h"
#include "iostream"
#include "render_manager.h"
#include "common.h"
#include "ui_font_header.h"
#include "nativeapi_deviceinfo.h"
#include "module_manager.h"

const char FONT_NAME[] = "SourceHanSansSC-Regular.otf";
static uint32_t g_fontPsramBaseAddr[OHOS::MIN_FONT_PSRAM_LENGTH / 4];

static void InitHalScreen() {
    OHOS::ScreenDeviceProxy::GetInstance()->SetDevice(&VirtualScreen::GetInstance());
    OHOS::InputDeviceManager::GetInstance()->Init();
    OHOS::InputDeviceManager::GetInstance()->Add(&MouseInput::GetInstance());
}

JsApp::JsApp() {
    jsAbility = new OHOS::ACELite::JSAbility();
}

JsApp::~JsApp() {
}

bool JsApp::Start() {
    isAppRunning = true;
    JsAppthread = std::thread(JsApp::Run);
    if(JsAppthread.joinable()) {
        JsAppthread.detach();
    } else {
        return false;
    }
    return true;
}

bool JsApp::Stop() {
    std::cout << "[INFO]:JsApp Stop" << std::endl;
    jsAbility->TransferToDestroy();
    //JsAppthread.~thread();
    isAppRunning = false;
    return true;
}

JsApp &JsApp::GetInstance() {
    static JsApp instance;
    return instance;
}

void JsApp::Run() {
    std::cout << "[INFO]:JsApp Run" << std::endl;
    OHOS::GraphicStartUp::Init();
    InitHalScreen();
    OHOS::GraphicStartUp::InitFontEngine(reinterpret_cast<uintptr_t>(g_fontPsramBaseAddr), OHOS::MIN_FONT_PSRAM_LENGTH,
                                         const_cast<char *>((ApplicationPath()+"\\font\\").c_str()), const_cast<char *>(FONT_NAME));
    VirtualScreen::GetInstance().Init(protocalMsg.devices[0].screen.width, protocalMsg.devices[0].screen.height);
    JsApp::GetInstance().StartJsApp();
    while(isAppRunning) {
        OHOS::RenderManager::GetInstance().Callback();
        if(m_send == true) {
            if(VirtualScreen::GetInstance().screenBuffer == nullptr) {

            }else {
                if(isChanged == true) {
                    sendImg(&Simulator_Server, web_hdl,VirtualScreen::GetInstance().screenBuffer, VirtualScreen::GetInstance().GetWidth()*VirtualScreen::GetInstance().GetHeight() * 4,websocketpp::frame::opcode::value::binary);
                    isChanged = false;
                }
            }
        }

        std::this_thread::sleep_for(std::chrono::milliseconds(30));
    }
}

void JsApp::SetUuid(std::string id) {
    uuid = id;
    std::string appPath = ApplicationPath() + "/file_system/" + uuid.c_str();
    MKDIR(appPath.c_str());
}

void JsApp::StartJsApp() {
    jsAbility->Launch(jsAppPath.c_str(), uuid.c_str(), 0);
}

void JsApp::SetJsAppPath(const std::string &value) {
    jsAppPath = value;
}

void JsApp::SetJSHeapSize(uint32_t size) {
    JSHeapSize = size;
}

void JsApp::SetWidth(uint16_t width) {
    this->width = width;
}

void JsApp::SetHeight(uint16_t height) {
    this->height = height;
}

uint16_t JsApp::GetWidth() const {
    return width;
}

uint16_t JsApp::GetHeight() const {
    return height;
}
